﻿namespace Refract.Navigation
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;

    public class SiteMapNode
    {
        #region Constructors

        public SiteMapNode()
        {
            SiteMapNodeList = new Collection<SiteMapNode>();
        }

        #endregion Constructors

        #region Properties

        public string Name
        {
            get; set;
        }

        public ICollection<SiteMapNode> SiteMapNodeList
        {
            get; set;
        }

        public string Title
        {
            get; set;
        }

        public string ViewAssembly
        {
            get; set;
        }

        public string ViewTypeName
        {
            get; set;
        }

        #endregion Properties

        #region Methods

        public SiteMapNode CreateNode(string path)
        {
            SiteMapNode foundNode = null;

            string nextNodeName = ParsePath(path, out path);

            SiteMapNode currentNode = FindNode(nextNodeName);
            if (currentNode == null)
            {
                currentNode = new SiteMapNode() { Name = nextNodeName };
            }

            foundNode = currentNode.CreateNode(path);

            return foundNode;
        }

        public SiteMapNode SearchNode(string path)
        {
            SiteMapNode foundNode = null;

            if (string.IsNullOrEmpty(path)) return null;

            string nextNodeName = ParsePath(path, out path);

            foundNode = FindNode(nextNodeName);

            if (foundNode == null) return null;

            if (path != null)
            {
                foundNode = foundNode.SearchNode(path);
            }

            return foundNode;
        }

        private SiteMapNode FindNode(string nextNodeName)
        {
            SiteMapNode foundNode = (from node in SiteMapNodeList
                                     where node.Name == nextNodeName
                                     select node).FirstOrDefault();
            return foundNode;
        }

        private string ParsePath(string path, out string newPath)
        {
            int index = path.IndexOf('/');

            string nextNodeName;

            if (index > 0)
            {
                nextNodeName = path.Substring(0, index - 1);
                newPath = path.Substring(index + 1);
            }
            else
            {
                nextNodeName = path;
                newPath = null;
            }

            return nextNodeName;
        }

        #endregion Methods

        #region Other

        //public void GetView(string path, Action<View> viewReadyCallback)
        //{
        //    View foundView = null;
        //    var node = SiteMap.SearchNode(path);
        //    if (node == null) throw new InvalidOperationException("Node not found at path " + path);
        //    if (!string.IsNullOrEmpty(node.ViewAssembly))
        //    {
        //        ModuleService.EnsureModuleIsLoaded(node.ViewAssembly, () => foundView = GetView(node.ViewTypeName));
        //    }
        //    else
        //    {
        //        foundView = GetView(node.ViewTypeName);
        //    }
        //    if (viewReadyCallback != null)
        //    {
        //        viewReadyCallback(foundView);
        //    }
        //}
        //private View GetView(string viewTypeName)
        //{
        //    object foundObject = ContainerLocator.Container.GetExport(viewTypeName);
        //    if (foundObject is View) return (View)foundObject;
        //    else return null;
        //}
        //public void OnImportsSatisfied()
        //{
        //    bool siteMapChanged = false;
        //    foreach (var view in ImportedViewCollection)
        //    {
        //        if (!String.IsNullOrEmpty(view.Metadata.SiteMapPath))
        //        {
        //            var targetNode = SiteMap.SearchNode(view.Metadata.SiteMapPath);
        //            if (targetNode == null)
        //            {
        //                targetNode = SiteMap.CreateNode(view.Metadata.SiteMapPath);
        //                targetNode.Title = view.Metadata.Title;
        //                targetNode.ViewTypeName = view.Metadata.ViewName;
        //                siteMapChanged = true;
        //            }
        //        }
        //    }
        //    if (siteMapChanged) RaisePropertyChanged(new { SiteMap });
        //}

        #endregion Other
    }
}